package com.tsf.hbase.config;

import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
import org.apache.hadoop.hbase.regionserver.BloomType;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HBase Configure properties the object.
 *
 * @author taoningbo
 * @since 1.0
 */
@ConfigurationProperties(prefix = "spring.hbase")
public class HBaseProperties {

    /**
     * see <tt>hbase.tables</tt>
     * @see Table
     */
    private List<Table> tables = new ArrayList<>();

    /**
     * see <tt>hbase.zookeeper.quorum</tt>
     */
    private String quorum;

    /**
     * see <tt>hbase.zookeeper.property.clientPort</tt>
     */
    private String clientPort;

    /**
     * see <tt>hbase.master</tt>
     */
    private String master;

    /**
     * see <tt>hbase.client.write.buffer</tt>
     */
    private String writeBuffer = "10485760";

    /**
     * Extend or customize the configuration.
     * <pre>
     *     "hbase.client.pause"->"200"
     *     "hbase.client.retries.number"->"11"
     *     "hbase.ipc.client.tcpnodelay"->"true"
     *     "hbase.client.scanner.caching"->"1"
     * </pre>
     */
    private Map<String, String> properties = new HashMap<>();

    /**
     * Minimum connection size, default is 4.
     */
    private Integer minConnectionSize = 4;

    /**
     * Is equivalent to <tt>hbase.htable.threads.max</tt>
     */
    private Integer maxConnectionSize = 8;

    public HBaseProperties() {
        properties.put("hbase.client.pause",           "200");
        properties.put("hbase.client.retries.number",   "11");
        properties.put("hbase.ipc.client.tcpnodelay", "true");
        properties.put("hbase.client.scanner.caching",   "1");
        properties.put("hbase.table.sanity.checks",  "false");
    }

    public List<Table> getTables() {
        return tables;
    }

    public void setTables(List<Table> tables) {
        this.tables = tables;
    }

    public String getQuorum() {
        return quorum;
    }

    public void setQuorum(String quorum) {
        this.quorum = quorum;
    }

    public String getClientPort() {
        return clientPort;
    }

    public void setClientPort(String clientPort) {
        this.clientPort = clientPort;
    }

    public String getMaster() {
        return master;
    }

    public void setMaster(String master) {
        this.master = master;
    }

    public String getWriteBuffer() {
        return writeBuffer;
    }

    public void setWriteBuffer(String writeBuffer) {
        this.writeBuffer = writeBuffer;
    }

    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public Integer getMinConnectionSize() {
        return minConnectionSize;
    }

    public void setMinConnectionSize(Integer minConnectionSize) {
        this.minConnectionSize = minConnectionSize;
    }

    public Integer getMaxConnectionSize() {
        return maxConnectionSize;
    }

    public void setMaxConnectionSize(Integer maxConnectionSize) {
        this.maxConnectionSize = maxConnectionSize;
    }

    public static class Table {

        /**
         * see <tt>hbase.htable.name</tt>.
         */
        private String tableName;

        /**
         * see <tt>hbase.htable.family.name</tt>
         */
        private String[] familyNames;

        /**
         * 是否启用压缩，默认为启用，请看{@link HTableDescriptor#DEFAULT_COMPACTION_ENABLED}
         */
        private Boolean compactionEnabled = HTableDescriptor.DEFAULT_COMPACTION_ENABLED;

        /**
         * (COMPRESSION)压缩方式，默认‘LZO’，更多支持压缩方式请参考{@link Algorithm}
         */
        private Algorithm compression = Algorithm.LZO;

        /**
         * (BLOCKCACHE)是否开启blockCache，‘true’表示开启，‘false’表示关闭， 默认值请看{@link HColumnDescriptor#DEFAULT_BLOCKCACHE}
         */
        private Boolean blockCache = HColumnDescriptor.DEFAULT_BLOCKCACHE;

        /**
         * (BLOCKSIZE)hbase的BLOCKSIZE的值，默认为{@link HColumnDescriptor#DEFAULT_BLOCKSIZE}
         */
        private Integer blockSize = HColumnDescriptor.DEFAULT_BLOCKSIZE;

        /**
         * (BLOOMFILTER)支持过滤条件，默认按照‘ROW’行进行过滤，请看{@link HColumnDescriptor#DEFAULT_BLOOMFILTER}
         */
        private BloomType bloomFilterType = BloomType.valueOf(HColumnDescriptor.DEFAULT_BLOOMFILTER);

        /**
         * (TTL)数据过期时间，不填写表示使用hbase内部默认值，默认值请看{@link HColumnDescriptor#DEFAULT_TTL}
         */
        private Integer timeToLive = HColumnDescriptor.DEFAULT_TTL;

        /**
         * (SPLITS)预分区的字符集，不填写表示不预分区
         */
        private String splitKeys;

        public String getTableName() {
            return tableName;
        }

        public void setTableName(String tableName) {
            this.tableName = tableName;
        }

        public String[] getFamilyNames() {
            return familyNames;
        }

        public void setFamilyNames(String[] familyNames) {
            this.familyNames = familyNames;
        }

        public Boolean getCompactionEnabled() {
            return compactionEnabled;
        }

        public void setCompactionEnabled(Boolean compactionEnabled) {
            this.compactionEnabled = compactionEnabled;
        }

        public Algorithm getCompression() {
            return compression;
        }

        public void setCompression(Algorithm compression) {
            this.compression = compression;
        }

        public Boolean getBlockCache() {
            return blockCache;
        }

        public void setBlockCache(Boolean blockCache) {
            this.blockCache = blockCache;
        }

        public Integer getBlockSize() {
            return blockSize;
        }

        public void setBlockSize(Integer blockSize) {
            this.blockSize = blockSize;
        }

        public BloomType getBloomFilterType() {
            return bloomFilterType;
        }

        public void setBloomFilterType(BloomType bloomFilterType) {
            this.bloomFilterType = bloomFilterType;
        }

        public Integer getTimeToLive() {
            return timeToLive;
        }

        public void setTimeToLive(Integer timeToLive) {
            this.timeToLive = timeToLive;
        }

        public String getSplitKeys() {
            return splitKeys;
        }

        public void setSplitKeys(String splitKeys) {
            this.splitKeys = splitKeys;
        }
    }
}
